/*****************************************************************//**
 * \file   AnsysAPDLReader_ET.cpp
 * \brief  AnsysAPDLReader_ET
 *
 * \author Wyatt
 * \date   May 2023
 *********************************************************************/
#include "AnsysAPDLReader_ET.h"
#include "CDBReader.h"
#include "Includes.h"

IMPLEMENT_CDB_READER(AnsysAPDLReader_ET, KEY_ET, "ET")
IMPLEMENT_CDB_READER(AnsysAPDLReader_ETBLOCK, KEY_ETBLOCK, "ETBLOCK")//2025年6月3日10:07:16 新增兼容hypermesh输出cdb格式
IMPLEMENT_CDB_READER(AnsysAPDLReader_KEYO, KEY_KEYO, "KEYO")

AnsysAPDLReader_ET::AnsysAPDLReader_ET(CDBReader* pCDBReader)
	: ReaderBase(pCDBReader)
{
}

bool AnsysAPDLReader_ET::Scan(std::string& strDataLine)
{
	_inBlock = IN_YES;
	return true;
}

bool AnsysAPDLReader_ET::Read(std::string& strDataLine)
{
	std::vector<std::string> vecData;
	int n = split(strDataLine, vecData);
	int eid = 0;
	int typeId = 0;
	SNum6d v(DEFAUL_DBL, DEFAUL_DBL, DEFAUL_DBL, DEFAUL_DBL, DEFAUL_DBL, DEFAUL_DBL);
	for (int i = 0; i < n; i++)
	{
		std::string data = vecData[i];		
		removeInvalid(data);
		switch (i)
		{
		case 0:
			toUpper(data);
			if (data != "ET")
				return false;
			break;
		case 1:
			if (!string2Integer(data, eid))
			{
				if (_pCDBReader->_mulSet.find(data) != _pCDBReader->_mulSet.end())
				{
					if (!string2Integer(_pCDBReader->_mulSet[data], eid))
					{
						return false;
					}
				}
			}
			break;
		case 2:
			if (!string2Integer(data, typeId))
			{
				std::string strNum;
				if (!_pCDBReader->FindVariable(data, strNum))
					return false;
				if (!string2Integer(strNum, typeId))
					return false;
			}
			break;
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
			if (!string2Double(data, v[i - 3]))
				;
			break;
		case 9:
			break;
		}
	}

	if (If3DAnalysisElement(typeId)^CDBReader::AnalysisDimention3D)
	{
		//throw std::exception(" error.Analysis dimension is not match the element in the inp file.\n");
		//throw ReporterFatal<std::string>("Analysis dimension is not match the element in the cdb file.\n");
	}

	AnsysET* pET = new AnsysET;
	pET->eType = (AnsElemType::Type)typeId;
	pET->eid = eid;
	if (typeId == 154)
	{
		_pCDBReader->ifEleToSet = true;
		pET->ifOutPut = false;
	}
	else
	{
		_pCDBReader->ifEleToSet = false;
		pET->ifOutPut = true;
	}

	_pCDBReader->AddET(pET);

	return true;
}

AnsysAPDLReader_ETBLOCK::AnsysAPDLReader_ETBLOCK(CDBReader* pCDBReader)
	: ReaderBase(pCDBReader)
{
}

bool AnsysAPDLReader_ETBLOCK::Scan(std::string& strDataLine)
{
	_inBlock = IN_YES;
	return true;
}

bool AnsysAPDLReader_ETBLOCK::Read(std::string& strDataLine)
{
	std::vector<std::string> vecData;
	if (strDataLine.find("ETBLOCK")!= string::npos )
	{
		return true;
	}
	if (strDataLine.find("(") == 0)
	{
		return true;

	}
	int n = splitView(strDataLine, vecData, " ", true, true);
	int eid = 0;
	int typeId = 0;
	SNum6d v(DEFAUL_DBL, DEFAUL_DBL, DEFAUL_DBL, DEFAUL_DBL, DEFAUL_DBL, DEFAUL_DBL);
	for (int i = 0; i < n; i++)
	{
		std::string data = vecData[i];
		removeInvalid(data);
		switch (i)
		{
		case 0:
			toUpper(data);
			if (data == "ETBLOCK")
				return true;
			if (data.find('(') == 0)
				return true;
			if (!string2Integer(data, eid))
			{
				if (_pCDBReader->_mulSet.find(data) != _pCDBReader->_mulSet.end())
				{
					if (!string2Integer(_pCDBReader->_mulSet[data], eid))
					{
						return false;
					}
				}
			}
			
		case 1:
			if (!string2Integer(data, typeId))
			{
				std::string strNum;
				if (!_pCDBReader->FindVariable(data, strNum))
					return false;
				if (!string2Integer(strNum, typeId))
					return false;
			}
			break;
		case 2:
			
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
			break;
		case 9:
			break;
		}
	}

	if (If3DAnalysisElement(typeId) ^ CDBReader::AnalysisDimention3D)
	{
		//throw std::exception(" error.Analysis dimension is not match the element in the inp file.\n");
		//throw ReporterFatal<std::string>("Analysis dimension is not match the element in the cdb file.\n");
	}

	AnsysET* pET = new AnsysET;
	pET->eType = (AnsElemType::Type)typeId;
	pET->eid = eid;
	if (typeId == 154)
	{
		_pCDBReader->ifEleToSet = true;
		pET->ifOutPut = false;
	}
	else
	{
		_pCDBReader->ifEleToSet = false;
		pET->ifOutPut = true;
	}

	_pCDBReader->AddET(pET);

	return true;
}

AnsysAPDLReader_KEYO::AnsysAPDLReader_KEYO(CDBReader* pCDBReader)
	: ReaderBase(pCDBReader)
{
}

bool AnsysAPDLReader_KEYO::Read(std::string& strDataLine)
{
	std::vector<std::string> vecData;
	int n = split(strDataLine, vecData);
	int eid = 0;
	int typeId = 0;
	int num = 0;
	for (int i = 0; i < n; i++)
	{
		std::string data = vecData[i];
		switch (i)
		{
		case 1:
			if (!string2Integer(data, eid))
			{
				if (_pCDBReader->_mulSet.find(data) != _pCDBReader->_mulSet.end())
				{
					if (!string2Integer(_pCDBReader->_mulSet[data], eid))
					{
						return false;
					}
				}
				else
				{
					return false;
				}
			}
			break;
		case 2:
			if (!string2Integer(data, typeId))
			{
				return false;
			}
			break;
		case 3:
			if (!string2Integer(data, num))
			{
				return false;
			}
			break;
		default:
			break;
		}
	}

	AnsysET* pET = _pCDBReader->FindETById(eid);
	if (pET == nullptr)
	{
		return false;
	}

	if (pET->eType== AnsElemType::Type::SOLID185)
	{		
		if (typeId == 2)
		{
			switch (num)
			{
			case 0:
				break;
			case 1:
				pET->eleTechnology = SimElem::Opt::R;
				break;
			default:
				break;
			}
		}
	}
	else if (pET->eType == AnsElemType::Type::CONTA174)
	{
		auto iter = _pCDBReader->allContactEt.find(eid);
		std::shared_ptr<Ansys_Contact>& contactPtr = iter->second;
		Ansys_Contact174* con = dynamic_cast<Ansys_Contact174*>(contactPtr.get());
		if (iter != _pCDBReader->allContactEt.end())
		{
			if (typeId == 2)
			{
				//iter->second.algorithm = (ANSYS_CONTACT_ALGORITHM)num;
				con->algorithm == (ANSYS_CONTACT_ALGORITHM)num;
			}
			else if (typeId == 4)
			{
				//iter->second.constraint = (ANSYS_CONTACT_CONSTRAINT)num;
				con->constraint = (ANSYS_CONTACT_CONSTRAINT)num;
			}
			else if (typeId == 12)
			{
				//iter->second.behavior = (ANSYS_CONTACT_BEHAVIOR)num;
				con->behavior = (ANSYS_CONTACT_BEHAVIOR)num;
			}
		}
		else
		{
			return false;
		}
	}
	else if (pET->eType == AnsElemType::Type::TARGET170)
	{
		auto iter = _pCDBReader->allTargetEt.find(eid);
		if (iter != _pCDBReader->allTargetEt.end())
		{
			if (typeId == 4)
			{
				DIM_DOF dof = (DIM_DOF)0;
				for (int i = 0; i < 6; i++)
				{
					int comp = pow(10, (i + 1));
					int dofNum = num % comp;
					num -= dofNum;
					if (dofNum)
					{
						dof = (DIM_DOF)(dof | (DIM_DOF)((int)pow(2, i)));
					}
				}		
				iter->second.dof = dof;
			}
		}
		else
		{
			return false;
		}
	}
	else if (pET->eType == AnsElemType::Type::CONTA175)
	{
		auto iter = _pCDBReader->allContactEt.find(eid);
		std::shared_ptr<Ansys_Contact>& contactPtr = iter->second;
		Ansys_Contact175* con = dynamic_cast<Ansys_Contact175*>(contactPtr.get());
		if (iter != _pCDBReader->allContactEt.end())
		{
			if (typeId == 2)
			{
				//iter->second.algorithm = (ANSYS_CONTACT_ALGORITHM)num;
				con->algorithm == (ANSYS_CONTACT_ALGORITHM)num;
			}
			else if (typeId == 4)
			{
				//iter->second.constraint = (ANSYS_CONTACT_CONSTRAINT)num;
				con->constraint = (ANSYS_CONTACT_CONSTRAINT)num;
			}
			else if (typeId == 12)
			{
				//iter->second.behavior = (ANSYS_CONTACT_BEHAVIOR)num;
				con->behavior = (ANSYS_CONTACT_BEHAVIOR)num;
			}
		}
		else
		{
			return false;
		}
	}
	return true;
}
